home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 24 / AACD 24.iso / AACD / Online / Epic4 / share / epic / help / 7_docs / Expressions < prev    next >
Encoding:
Text File  |  2001-03-21  |  9.6 KB  |  224 lines

  1. Expression Syntax in EPIC                                                   
  2.  
  3. This document describes the "expression" context of a statement, as used with
  4. the ${} expando, the @ operator, and the FOR, IF, UNLESS, UNTIL, and WHILE
  5. commands.
  6.  
  7. The normal context is "text", meaning everything is assumed to be plain text,
  8. unless it is preceded by a '$'.  With "expression" context, everything is
  9. assumed to be a variable unless contained in square brackets '[]'.  To enter
  10. expression context explicitly while in text context, use the ${} notation.
  11. Unlike text context, whitespace is not significant in expression context
  12. (but see below).
  13.  
  14. The @ operator is a special case that allows any arbitrary expression to be
  15. evaluated.  Unlike the other commands listed above, however, the return
  16. value of the expression is always thrown away.  In many cases, the behavior
  17. of @ is much like that of EVAL.  The following statements are equivalent:
  18.  
  19.    @ foo = 3
  20.    @ ::foo = 3                      # two colons declare GLOBAL variables
  21.    eval (foo = 3)
  22.  
  23. Also note the use of variables local to a script's current scope. These could
  24. be assigned with the local(5) command as opposed to assign(5) for global
  25. variables. They can also be created with the @ operator (as shown above).
  26. The following statements are equivalent:
  27.  
  28.    @ :foo = 3                       # one colon declares LOCAL variables
  29.    local foo 3
  30.  
  31. EPIC's expression syntax is modeled after that of C++, and EPIC's operators
  32. (in general) hold the same precedence as they do in C++.  Most of the C/C++
  33. operator set is represented in EPIC, and their operation is the same.  The
  34. following operators, from highest to lowest precedence, are supported:
  35.  
  36.        1:   ()   []
  37.        2:   !    ~    ++   --
  38.        3:   *    /    %    **
  39.        4:   +    -    ##
  40.        5:   <    <=   >    >=   <<    >>
  41.        6:   ==   !=
  42.        7:   &
  43.        8:   ^
  44.        9:   |
  45.       10:   &&
  46.       11:   ^^
  47.       12:   ||
  48.       13:   ?:
  49.       14:   =    +=   -=   *=   /=   %=   &=   ^=   |=   #=   #~  =~   !~
  50.       15:   ,
  51.  
  52. The string concatenation operators, ##, #=, and #~, are a special case, as they
  53. are not present in C or C++.  As their name indicates, they are used to join
  54. two or more strings together, end to end.  For example:
  55.  
  56.    @ foo  = [foo] ## [bar]              /* sets $foo to "foobar" */
  57.    @ foo #= [blah]                      /* sets $foo to "foobarblah" */
  58.    @ foo #~ [hmm]                       /* sets $foo to "hmmfoobarblah" */
  59.  
  60. Also like C/C++, parentheses may be used to force certain parts of the
  61. expression to be evaluated first (mainly in the event that the user wishes
  62. for it to evaluate in an order other than that of operator precedence).
  63. Parentheses may be nested.  For example, if some variable $foo is set to 3:
  64.  
  65.    foo * 4 + 5                          /* returns 17 */
  66.    foo * (4 + 5)                        /* returns 27 */
  67.    4 + ((foo + 9) / 3)                  /* returns 8 */
  68.  
  69. All assignment operators always return the value assigned, which allows for
  70. the assignment of multiple variables at once.  Keep in mind that expressions
  71. are evaluated right to left.  For example, if $foo is 12 and $bar is 11:
  72.  
  73.    @ foo += bar *= 2                    /* $bar is 22, $foo is 34 */
  74.  
  75. Since the release of the EPIC4 pre-betas, the client has been growing ever
  76. more perlish. Like perl, the =~ and !~ operators match with wildcards. =~ is
  77. a direct opposite of !~, where it returns true if the patterns patch, while
  78. !~ returns false. In this example, $bar is "epic":
  79.    
  80.    @ foo = bar =~ [*pi*]               /* returns 1 */
  81.    @ foo = bar !~ [*z*]                /* returns 1 */
  82.  
  83. The various bitwise operators are of special interest also. Assuming $foo is 12
  84. and $bar is 11:
  85.  
  86.    foo & bar                            /* returns 8 */
  87.    foo | bar                            /* returns 15 */
  88.    foo ^ bar                            /* returns 7 */
  89.  
  90. The exponential operator takes numbers to various powers. It is especially
  91. useful, since many script writers create a $power() function for this purpose.
  92. It supports negative and fractional exponents as long as the system's math
  93. library (libm) does. Assuming $foo is 9:
  94.  
  95.    foo ** 2                             /* returns 81 */
  96.    foo ** 0.5                           /* returns 3 */
  97.  
  98. The {pre,post}fix {in,de}crement operators are big timesavers that C and C++
  99. users everywhere swear by.  They have also been known to swear at them, for
  100. reasons you will soon see.  Assume $foo is 5, each column shows 3 ways of
  101. doing the same thing, from least efficient to most efficient:
  102.  
  103.    @ foo  = foo + 1                     @ foo  = foo - 1
  104.    @ foo += 1                           @ foo -= 1
  105.    @ foo++                              @ foo--
  106.  
  107. However, these operators have pitfalls, which are mainly discovered by those
  108. who do not understand how they work.  Both may either prefix or postfix a
  109. variable; prefix causes it to evaluate before the operation, postfix causes
  110. it to evaluate aster.  For the examples shown above, it makes no difference.
  111. However, it does make a difference in this example:
  112.  
  113.    while ( foo++ < 10 ) { ... }
  114.  
  115. The expression is evaluated for whether $foo is less than 10, and then $foo
  116. is incremented.  If the autoincrement operator was instead used in prefix
  117. form, $foo would be incremented before the expression was evaluated, which
  118. would cause the loop to have one less iteration.
  119.  
  120. Another pitfall of the autoincrement and decrement operators is the
  121. ambiguity introduced by insufficient whitespace when used in conjunction
  122. with addition and subtraction operators.  Consider the following:
  123.  
  124.    @ foo    = 4
  125.    @ bar    = 8
  126.    @ foobar = foo+++bar
  127.  
  128. How should one interpret the last assignment?  Should it really look like
  129. ${foo++ + bar} or ${foo + ++bar}?  It's hard to tell.  The best solution is
  130. to not write code that looks so silly and unreadable.  Add a couple spaces,
  131. and there is no ambiguity.  (The answer is, the first one.)
  132.  
  133. Another popular operator familiar to most C/C++ programmers is the tertiary
  134. operator (sometimes referred to as the alternation operator).  It performs
  135. a function similar to IF, except is much more compact and efficient.  We'll
  136. let $foo be 5 again:
  137.  
  138.    @ bar = foo > 3 ? 1 : 0              /* sets $bar to 1 */
  139.    @ bar = foo > 8 ? 1 : 0              /* sets $bar to 0 */
  140.  
  141. Functions (builtin and scripted) can also be used within expressions.  The
  142. function will be evaluated, and its return value is used in the expression:
  143.  
  144.    @ foo = pattern(b* foo bar blah)     /* sets $foo to "bar blah" */
  145.  
  146. All functions implicitly use a special operator, ().  That is, the pair of
  147. parentheses themselves compose an operator, though of course it is somewhat
  148. different in nature from more traditional operators like '+' or '<' or '&'.
  149. Functions (aliases with return values) require the () to function properly.
  150.  
  151. A similar operator is [], which is used for alias and variable structures.
  152. We've already seen that it can be used to explicitly switch the evaluation
  153. context to text.  This can be extended to structure elements, such that
  154. they can be expanded on the fly:
  155.  
  156.    @ foo.1.1 = foo
  157.    @ foo.1.2 = bar
  158.    alias blah echo $foo[1][$0]
  159.    /blah 2                              /* expands to $foo.1.2 -> "bar" */
  160.  
  161. The same can be applied to aliases and functions as well.  Because of the
  162. nature of the [] operator, anything may be expanded inside it, variables and
  163. functions alike.
  164.  
  165. Operator parse tree:
  166.  
  167.        NU_POIX    = varexp++                     |
  168.                     varexp--                     |
  169.                     NU_EXPR   
  170.        NU_EXPR    = NU_ASSN
  171.        NU_ASSN    = varexp  = NU_ASSN            |
  172.                     varexp += NU_ASSN            |
  173.                     varexp -= NU_ASSN            |
  174.                     varexp *= NU_ASSN            |
  175.                     varexp /= NU_ASSN            |
  176.                     varexp %= NU_ASSN            |
  177.                     varexp &= NU_ASSN            |
  178.                     varexp ^= NU_ASSN            |
  179.                     varexp |= NU_ASSN            |
  180.                     varexp #= NU_ASSN            |
  181.                     NU_TERT
  182.        NU_TERT    = NU_COMP ? NU_COMP : NU_COMP  |
  183.                     NU_CONJ
  184.        NU_CONJ    = NU_CONJ && NU_CONJ           |
  185.                     NU_CONJ || NU_CONJ           |
  186.                     NU_CONJ ^^ NU_CONJ           |
  187.                     NU_BITW
  188.        NU_BITW    = NU_COMP & NU_COMP            |
  189.                     NU_COMP | NU_COMP            |
  190.                     NU_COMP ^ NU_COMP            |
  191.                     NU_COMP
  192.        NU_COMP    = NU_COMP == NU_COMP           |
  193.                     NU_COMP != NU_COMP           |
  194.                     NU_COMP >  NU_COMP           |
  195.                     NU_COMP >= NU_COMP           |
  196.                     NU_COMP <  NU_COMP           |
  197.                     NU_COMP <= NU_COMP           |
  198.                     NU_ADD
  199.        NU_ADD     = NU_ADD +  NU_ADD             |
  200.                     NU_ADD -  NU_ADD             |
  201.                     NU_ADD ## NU_ADD             |
  202.                     NU_MULT
  203.        NU_MULT    = NU_MULT * NU_MULT            |
  204.                     NU_MULT / NU_MULT            |
  205.                     NU_MULT % NU_MULT            |
  206.                     NU_UNIT
  207.        NU_UNIT    = token NUX_MODIF              |
  208.                     unaryop token                |
  209.                     ( NU_EXPR )                  |
  210.                     [ expression ] NUX_MODIF     |
  211.                     NU_PRIX
  212.        NU_PRIX    = ++varexp                     |
  213.                     --varexp
  214.  
  215.        NUX_MODIF  = ( expression ) NUX_MODIF     |
  216.                     [ expression ] NUX_MODIF
  217.  
  218.        unaryop    = !                            |
  219.                     ~
  220.  
  221. See Also:
  222.    Patterns(7); Programming(7); Special_Vars(7)
  223.  
  224.